#include "Geometric/Vertex.hpp"
#include "Geometric/Face.hpp"

namespace mif
{
	
	int Vertex::mVertexCount = 0;
	
	Vertex::Vertex()
	{
		//EMPTY
	}
	
	Vertex::Vertex(double pX, double pY, double pZ) :
		mID(mVertexCount++),
		mFace(nullptr)
	{
		mCoord.x = pX;
		mCoord.y = pY;
		mCoord.z = pZ;
	}
	
	Vertex::~Vertex()
	{
		//EMPTY
	}
	
	const int Vertex::GetID() const
	{
		return mID;
	}
	
	const Coord3D Vertex::GetCoord() const
	{
		return mCoord;
	}
			
	Face * Vertex::GetFace() const
	{
		return mFace;
	}
	
	void Vertex::SetFace(Face & pFaceAddress)
	{
		if(mFace == nullptr)
			mFace = &pFaceAddress;
	}
	
	Vertex * Vertex::begin()
	{
		return this;
	}
	
	Vertex * Vertex::end()
	{
		return this;
	}


	//--------- Faces Iterator ------------//


	Face Vertex::FacesIterator::operator *()
	{	
		return *mPtr;
	}

	Face* Vertex::FacesIterator::operator ->()
	{	
		return mPtr;
	}

	bool Vertex::FacesIterator::operator == (const FacesIterator& pIt)
	{
		return mPtr == pIt.mPtr;
	}
	
	bool Vertex::FacesIterator::operator != (const FacesIterator& pIt)
	{
	
		if(mFirstView && mPtr == pIt.mPtr){
			mFirstView = false;
			return true;
		}
		
		return mPtr != pIt.mPtr;
		
	}

	Vertex::FacesIterator& Vertex::FacesIterator::operator ++()
	{
	
		Vertex* vertexTab[]={mPtr->GetTriangle().a,mPtr->GetTriangle().b,mPtr->GetTriangle().c};
		
		for (int i = 0; i < 3; i++)
			if(vertexTab[i] == mVertex)
				mPtr= mPtr->GetNeighborhoodWithVertices(vertexTab[i],vertexTab[(i+1)%3]);
		
		return *this;
		
	}


	//--------- Vertices Iterator ------------//


	Vertex Vertex::VerticesIterator::operator *()
	{	
		return *(*mFaceIt).getNextVertex(mVertex);
	}

	Vertex* Vertex::VerticesIterator::operator ->()
	{	
		return (*mFaceIt).getNextVertex(mVertex);
	}

	bool Vertex::VerticesIterator::operator != (const VerticesIterator& pIt)
	{
	
		if(mFirstView && mFaceIt != pIt.mFaceIt){
			mFirstView= false;
			return true;
		}
		return mFaceIt != pIt.mFaceIt;
		
	}
	
	bool Vertex::VerticesIterator::operator == (const VerticesIterator& pIt)
	{
		return mFaceIt == pIt.mFaceIt;
	}


	Vertex::VerticesIterator& Vertex::VerticesIterator::operator ++()
	{
		++mFaceIt;
		return *this;
	}

}
